package com.test45_JUC;

import java.util.concurrent.*;

/**
 * BlockingQueue，单端阻塞队列
 * 为了解决项目开发之中这种多线程存储关系队列的操作问题，提供了一个阻塞队列的概念，可以把这种队列理解为自动的队列。
 * 当进行数据写入的时候，如果发现队列已经满了，则不再写入，自动进入到阻塞状态。
 * 而在进行数据读取的时候，如果发现队列是空的，则也不再直接读取，而是进入到一种阻塞状态，等待有数据出现之后再次进行自动唤醒。
 */
public class Demo20_BlockingQueue {

    public static void main(String[] args) {
        // test1();
        // test2();
        // test3();
        test4();
    }

    /**
     * ArrayBlockingQueue，数组阻塞队列
     */
    public static void test1() {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(5);
        for (int x = 0; x < 10; x++) {
            final int temp = x;
            new Thread(() -> {
                for (int y = 0; y < 100; y++) {  // 持续生产
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        // String msg = "{ID = MUYAN - " + temp + " - " + y + "}沐言科技：www.yootk.com";
                        String msg = String.format("{ID = MUYAN - %d - %d}沐言科技：www.yootk.com", temp, y);
                        queue.put(msg);
                        System.out.printf("【%s】%s%n", Thread.currentThread().getName(), msg);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "YOOTK生产者-"+x).start();
        }

        for (int x = 0; x < 2; x++) {
            new Thread(() -> {
                while (true) {  // 持续性的通过队列取数据
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        System.err.printf("【%s】%s%n", Thread.currentThread().getName(), queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "YOOTK消费者-"+x).start();
        }
    }

    /**
     * LinkedBlockingQueue，链表阻塞队列
     */
    public static void test2() {
        BlockingQueue<String> queue = new LinkedBlockingQueue<>(5);
        for (int x = 0; x < 10; x++) {
            final int temp = x;
            new Thread(() -> {
                for (int y = 0; y < 100; y++) {  // 持续生产
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        String msg = String.format("{ID = MUYAN - %d - %d}沐言科技：www.yootk.com", temp, y);
                        queue.put(msg);
                        System.out.printf("【%s】%s%n", Thread.currentThread().getName(), msg);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "YOOTK生产者-"+x).start();
        }

        for (int x = 0; x < 2; x++) {
            new Thread(() -> {
                while (true) {  // 持续性的通过队列取数据
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        System.err.printf("【%s】%s%n", Thread.currentThread().getName(), queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "YOOTK消费者-"+x).start();
        }
    }

    /**
     * PriorityBlockingQueue，优先级阻塞队列
     */
    public static void test3() {
        BlockingQueue<String> queue = new PriorityBlockingQueue<>(5);
        for (int x = 0; x < 10; x++) {
            final int temp = x;
            new Thread(() -> {
                for (int y = 0; y < 100; y++) {  // 持续生产
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        String msg = String.format("{ID = MUYAN - %d - %d}沐言科技：www.yootk.com", temp, y);
                        queue.put(msg);
                        System.out.printf("【%s】%s%n", Thread.currentThread().getName(), msg);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "YOOTK生产者-"+x).start();
        }

        for (int x = 0; x < 2; x++) {
            new Thread(() -> {
                while (true) {  // 持续性的通过队列取数据
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        System.err.printf("【%s】%s%n", Thread.currentThread().getName(), queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "YOOTK消费者-"+x).start();
        }
    }

    /**
     * SynchronousQueue，同步阻塞队列（单一队列）
     */
    public static void test4() {
        BlockingQueue<String> queue = new SynchronousQueue<>();
        for (int x = 0; x < 10; x++) {
            final int temp = x;
            new Thread(() -> {
                for (int y = 0; y < 10; y++) {  // 持续生产
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        String msg = String.format("{ID = MUYAN - %d - %d}沐言科技：www.yootk.com", temp, y);
                        queue.put(msg);
                        System.out.printf("【%s】%s%n", Thread.currentThread().getName(), msg);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "YOOTK生产者-"+x).start();
        }

        for (int x = 0; x < 2; x++) {
            new Thread(() -> {
                while (true) {  // 持续性的通过队列取数据
                    try {
                        TimeUnit.SECONDS.sleep(2);
                        System.err.printf("【%s】%s%n", Thread.currentThread().getName(), queue.take());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "YOOTK消费者-"+x).start();
        }
    }
}
